#pragma once

namespace SD_Tools
{
	class AbstractDraw
	{
		private:
			static bool FloatNear(float a, float b, float Range);
			static float AbstractDraw::RadToDeg(float alpha);
			static float AbstractDraw::DegToRad(float alpha);

		public:
			static SHAPEVERTEX* AcquireShapeBuffer(int NumberOfVertices);
			static TEXVERTEX* AcquireTextureBuffer(int NumberOfVertices);

			static void ReleaseShapeBuffer(SHAPEVERTEX* Buffer);
			static void ReleaseTextureBuffer(TEXVERTEX* Buffer);

			static HRESULT PrepareStateBlock(IDirect3DDevice9* Device, IDirect3DStateBlock9** StateBlock);
			static void BeginStateBlock(IDirect3DDevice9* Device, IDirect3DStateBlock9* StateBlock, DWORD FVFType);
			static HRESULT EndStateBlock(IDirect3DStateBlock9* StateBlock);

			static HRESULT CreateFont_SD(IDirect3DDevice9* Device, int Size, UINT Weight, bool Italic, wchar_t* Name, ID3DXFont** Out);

			
			static int CreatePoint(SHAPEVERTEX* Buffer, Vector2 Point, D3DCOLOR Color);
			

			static int CreateLine(SHAPEVERTEX* Buffer, Vector2 Point1, Vector2 Point2, D3DCOLOR Color);
			static int CreateLine(SHAPEVERTEX* Buffer, Vector2 Point1, Vector2 Point2, D3DCOLOR Color1, D3DCOLOR Color2);

			static int CreateMultiLine(SHAPEVERTEX* Buffer, Vector2* Points, int NumberOfPoints, D3DCOLOR Color);
			static int CreateMultiLine(SHAPEVERTEX* Buffer, Vector2* Points, int NumberOfPoints, D3DCOLOR* Colors);

			static int CreateOutlineTriangle(SHAPEVERTEX* Buffer, Vector2 Point1, Vector2 Point2, Vector2 Point3, D3DCOLOR Color);
			static int CreateOutlineTriangle(SHAPEVERTEX* Buffer, Vector2 Point1, Vector2 Point2, Vector2 Point3, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3);

			static int CreateOutlineRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, D3DCOLOR Color);
			static int CreateOutlineRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4);

			static int CreateOutlineCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color);
			static int CreateOutlineOutCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color);
			static int CreateOutlineCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color1, D3DCOLOR Color2);

			static int CreateOutlineBorderCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, Vector2 Size, D3DCOLOR Color);
			static int CreateOutlineBorderCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, Vector2 Size, D3DCOLOR Color1, D3DCOLOR Color2);

			static int CreateOutlineRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color);
			static int CreateOutlineOutRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color);
			static int CreateOutlineRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4, D3DCOLOR Color5, D3DCOLOR Color6, D3DCOLOR Color7, D3DCOLOR Color8);
			static int CreateOutlineOutRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4);

			
			static int CreateTriangle(SHAPEVERTEX* Buffer, Vector2 Position1, Vector2 Position2, Vector2 Position3, D3DCOLOR Color);
			static int CreateTriangle(SHAPEVERTEX* Buffer, Vector2 Position1, Vector2 Position2, Vector2 Position3, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3);

			static int CreateQuad(SHAPEVERTEX* Buffer, Vector2 Position1, Vector2 Position2, Vector2 Position3, Vector2 Position4, D3DCOLOR Color);
			static int CreateQuad(SHAPEVERTEX* Buffer, Vector2 Position1, Vector2 Position2, Vector2 Position3, Vector2 Position4, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4);

			static int CreateRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, D3DCOLOR Color);
			static int CreateRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4);

			static int CreateMultiShape(SHAPEVERTEX* Buffer, Vector2* Points, int NumberOfPoints, D3DCOLOR Color);
			static int CreateMultiShape(SHAPEVERTEX* Buffer, Vector2* Points, int NumberOfPoints, D3DCOLOR* Colors);

			static int CreateCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color);
			static int CreateCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color1, D3DCOLOR Color2);

			static int CreateBorderCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, Vector2 Size, D3DCOLOR Color);
			static int CreateBorderCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, Vector2 Size, D3DCOLOR Color1, D3DCOLOR Color2);

			static int CreateRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color);
			static int CreateRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4, D3DCOLOR Color5, D3DCOLOR Color6, D3DCOLOR Color7, D3DCOLOR Color8);

			static void MoveShapeBufferRelative(SHAPEVERTEX* Buffer, Vector2 Direction, int NumberOfVertices);
			static void MoveShapeBufferAbsolute(SHAPEVERTEX* Buffer, Vector2 Point, int NumberOfVertices);

			static void MoveTextureBufferRelative(TEXVERTEX* Buffer, Vector2 Direction, int NumberOfVertices);
			static void MoveTextureBufferAbsolute(TEXVERTEX* Buffer, Vector2 Point, int NumberOfVertices);

			static HRESULT CreateSprite(IDirect3DDevice9* Device, ID3DXSprite** OutSprite );
			static HRESULT BeginSprite(ID3DXSprite* Sprite);
			static HRESULT EndSprite(ID3DXSprite* Sprite);
			static HRESULT SpriteResetA(ID3DXSprite* Sprite);
			static HRESULT SpriteResetB(ID3DXSprite* Sprite);

			static int DrawText(ID3DXFont* Font, ID3DXSprite* Sprite, Vector2 Point, D3DCOLOR Color, DrawTextType Type, char* text);
			static int DrawText(ID3DXFont* Font, ID3DXSprite* Sprite, Vector2 Point, D3DCOLOR Color, DrawTextType Type, wchar_t* text);
			static int DrawTextFormat(ID3DXFont* Font, ID3DXSprite* Sprite, Vector2 Point, D3DCOLOR Color, DrawTextType Type, char* text, ...);
			static int DrawTextFormat(ID3DXFont* Font, ID3DXSprite* Sprite, Vector2 Point, D3DCOLOR Color, DrawTextType Type, wchar_t* text, ...);

			static int DrawText(ID3DXFont* Font, ID3DXSprite* Sprite, Rectangle2 Rect, D3DCOLOR Color, DrawTextType Type, char* text);
			static int DrawText(ID3DXFont* Font, ID3DXSprite* Sprite, Rectangle2 Rect, D3DCOLOR Color, DrawTextType Type, wchar_t* text);
			static int DrawTextFormat(ID3DXFont* Font, ID3DXSprite* Sprite, Rectangle2 Rect, D3DCOLOR Color, DrawTextType Type, char* text, ...);
			static int DrawTextFormat(ID3DXFont* Font, ID3DXSprite* Sprite, Rectangle2 Rect, D3DCOLOR Color, DrawTextType Type, wchar_t* text, ...);

			static HRESULT FontResetA(ID3DXFont* Font);
			static HRESULT FontResetB(ID3DXFont* Font);

			static HRESULT TextureResetA(IDirect3DTexture9* Texture);
			static HRESULT TextureResetB(IDirect3DDevice9* Device, IDirect3DTexture9** Texture);
			static HRESULT TextureResetB(IDirect3DDevice9* Device, UINT Width, UINT Height, IDirect3DTexture9** Texture);
			static HRESULT TextureResetB(IDirect3DDevice9* Device, wchar_t* Path, IDirect3DTexture9** Texture);

			static HRESULT StateBlockResetA(IDirect3DStateBlock9* StateBlock);
			static HRESULT StateBlockResetB(IDirect3DDevice9* Device, IDirect3DStateBlock9** StateBlock);

			static HRESULT ClearRenderTarget(IDirect3DDevice9* Device);
			static HRESULT SetFVF(IDirect3DDevice9* Device, DWORD FVF);

			static int CreateTextureRectangle(TEXVERTEX* Buffer, Rectangle2 Rect);
			
			static HRESULT SetTexture(IDirect3DDevice9* Device, IDirect3DTexture9* Texture);

			static HRESULT DrawBuffer(IDirect3DDevice9* Device, D3DPRIMITIVETYPE Type, UINT NumberOfPrimitives, SHAPEVERTEX* Buffer);
			static HRESULT DrawPointBuffer(IDirect3DDevice9* Device, UINT NumberOfVertices, SHAPEVERTEX* Buffer);
			static HRESULT DrawLineBuffer(IDirect3DDevice9* Device, UINT NumberOfVertices, SHAPEVERTEX* Buffer);
			static HRESULT DrawTriangleBuffer(IDirect3DDevice9* Device, UINT NumberOfVertices, SHAPEVERTEX* Buffer);
			static HRESULT DrawTextureBuffer(IDirect3DDevice9* Device, UINT NumberOfVertices, TEXVERTEX* Buffer);


			static HRESULT CreateTexture(IDirect3DDevice9* Device, UINT Width, UINT Height, IDirect3DTexture9** Texture);
			static HRESULT CreateTexture(IDirect3DDevice9* Device, wchar_t* Path, IDirect3DTexture9** Texture);
			static HRESULT BeginTextureRender(IDirect3DDevice9* Device, IDirect3DTexture9* Texture, IDirect3DSurface9** OldSurface);
			static HRESULT EndTextureRender(IDirect3DDevice9* Device, IDirect3DSurface9* OldSurface);
	};

	bool AbstractDraw::FloatNear(float a, float b, float Range)
	{
		return (b-Range < a && b+Range > a);
	}
	
	float AbstractDraw::RadToDeg(float alpha)
	{
		return  (alpha*(180.0f/3.1415926535f));
	}

	float AbstractDraw::DegToRad(float alpha)
	{
		return  (alpha/(180.0f/3.1415926535f));
	}


	//************************************
	// Method:    AcquireShapeBuffer
	// Profit:	  Allocates a ShapeBuffer
	// FullName:  SD_Tools::AbstractDraw::AcquireShapeBuffer
	// Returns:   SHAPEVERTEX*
	// Notes:
	// -Call ReleaseShapeBuffer after use
	//************************************
	SHAPEVERTEX* AbstractDraw::AcquireShapeBuffer(int NumberOfVertices)
	{
		return new SHAPEVERTEX[NumberOfVertices];
	}

	//************************************
	// Method:    AcquireTextureBuffer
	// Profit:	  Allocates a TextureBuffer
	// FullName:  SD_Tools::AbstractDraw::AcquireTextureBuffer
	// Returns:   TEXVERTEX*
	// Notes:
	// -Call ReleaseTextureBuffer after use
	//************************************
	TEXVERTEX* AbstractDraw::AcquireTextureBuffer(int NumberOfVertices = 6)
	{
		return new TEXVERTEX[NumberOfVertices];
	}

	//************************************
	// Method:    ReleaseShapeBuffer
	// Profit:	  Releases a ShapeBuffer
	// FullName:  SD_Tools::AbstractDraw::ReleaseShapeBuffer
	// Returns:   void
	// Notes:
	// -None
	//************************************
	void AbstractDraw::ReleaseShapeBuffer(SHAPEVERTEX* Buffer)
	{
		delete[] Buffer;
	}

	//************************************
	// Method:    ReleaseTextureBuffer
	// Profit:	  Releases a TextureBuffer
	// FullName:  SD_Tools::AbstractDraw::ReleaseTextureBuffer
	// Returns:   void
	// Notes:
	// -None
	//************************************
	void AbstractDraw::ReleaseTextureBuffer(TEXVERTEX* Buffer)
	{
		delete[] Buffer;
	}

	//************************************
	// Method:    PrepareStateBlock
	// Profit:	  Creates A StateBlock
	// FullName:  SD_Tools::AbstractDraw::PrepareStateBlock
	// Returns:   HRESULT
	// Notes:
	// -Just a Wrapper for CreateStateBlock with "D3DSBT_ALL"
	//************************************
	HRESULT AbstractDraw::PrepareStateBlock(IDirect3DDevice9* Device, IDirect3DStateBlock9** StateBlock)
	{
		return Device->CreateStateBlock(D3DSBT_ALL, StateBlock);
	}

	//************************************
	// Method:    BeginStateBlock
	// Profit:	  Captures current States and change many of them to "good" values
	// FullName:  SD_Tools::AbstractDraw::BeginStateBlock
	// Returns:   void
	// Notes:
	// -Call EndStateBlock after use
	// -Thanks to KN4CK3R from http://www.oldschoolhack.de/ for main part of this function
	//************************************
	void AbstractDraw::BeginStateBlock(IDirect3DDevice9* Device, IDirect3DStateBlock9* StateBlock, DWORD FVFType = 0)
	{
		StateBlock->Capture();
		
		Device->SetFVF(FVFType);
		Device->SetTexture(0, 0);
		Device->SetVertexShader(0);
		Device->SetPixelShader(0);

		for(unsigned int n = 0; n < 8; ++n)
		{
			Device->SetTextureStageState(n,	D3DTSS_COLOROP, D3DTOP_MODULATE);
			Device->SetTextureStageState(n,	D3DTSS_COLORARG1, D3DTA_TEXTURE);
			Device->SetTextureStageState(n,	D3DTSS_COLORARG2, D3DTA_DIFFUSE);
			Device->SetTextureStageState(n,	D3DTSS_ALPHAOP, D3DTOP_DISABLE);
			Device->SetSamplerState(n, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
			Device->SetSamplerState(n, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
			Device->SetSamplerState(n, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC);
			Device->SetSamplerState(n, D3DSAMP_MAXANISOTROPY, 0);
		}

		Device->SetRenderState(D3DRS_LIGHTING, FALSE);
		Device->SetRenderState(D3DRS_FOGENABLE, FALSE);
		Device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
		Device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
		Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
		Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
		Device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
		Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
		Device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); // FALSE

		// setup texture addressing settings
		Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
		Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

		// setup colour calculations
		Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
		Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);

		// setup alpha calculations
		Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
		Device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
		Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

		// setup filtering
		Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
		Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

		// disable texture stages we do not need.
		Device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);

		// setup scene alpha blending
		Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

		Device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
		Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
		Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
		Device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_INVDESTALPHA);
		Device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ONE);
	}

	//************************************
	// Method:    EndStateBlock
	// Profit:	  Applies the saved StateBlock
	// FullName:  SD_Tools::AbstractDraw::EndStateBlock
	// Returns:   HRESULT
	// Notes:
	// -None
	//************************************
	HRESULT AbstractDraw::EndStateBlock(IDirect3DStateBlock9* StateBlock)
	{
		return StateBlock->Apply();
	}


	//************************************
	// Method:    CreateFont_SD
	// Profit:	  Creates a Font
	// FullName:  SD_Tools::AbstractDraw::CreateFont_SD
	// Returns:   HRESULT
	// Notes:
	// -is just a Wrapper for D3DXCreateFont
	// -Parameters: "DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE"
	//************************************
	HRESULT AbstractDraw::CreateFont_SD(IDirect3DDevice9* Device, int Size, UINT Weight, bool Italic, wchar_t* Name, ID3DXFont** Out)
	{
		return D3DXCreateFont(Device, Size, 0, Weight, 0, Italic, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, Name, Out);
	}

	//************************************
	// Method:    CreatePoint
	// Profit:	  Creates a Point
	// FullName:  SD_Tools::AbstractDraw::CreatePoint
	// Returns:   int Size used
	// Notes:
	// -Size = 1
	//************************************
	int AbstractDraw::CreatePoint(SHAPEVERTEX* Buffer, Vector2 Point, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer[0].color = Color;
			Buffer[0].rhw = 1.0f;
			Buffer[0].x = Point.x;
			Buffer[0].y = Point.y;
			Buffer[0].z = 0.0f;
		}
		return SIZE_POINT;
	}

	//************************************
	// Method:    CreateLine
	// Profit:	  Creates a Line
	// FullName:  SD_Tools::AbstractDraw::CreateLine
	// Returns:   int Size used
	// Notes:
	// -Size = 2
	//************************************
	int AbstractDraw::CreateLine(SHAPEVERTEX* Buffer, Vector2 Point1, Vector2 Point2, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer[0].color = Color;
			Buffer[0].rhw = 1.0f;
			Buffer[0].x = Point1.x;
			Buffer[0].y = Point1.y;
			Buffer[0].z = 0.0f;
			
			Buffer[1].color = Color;
			Buffer[1].rhw = 1.0f;
			Buffer[1].x = Point2.x;
			Buffer[1].y = Point2.y;
			Buffer[1].z = 0.0f;
		}
		return SIZE_LINE;
	}

	//************************************
	// Method:    CreateLine
	// Profit:	  Creates a Line
	// FullName:  SD_Tools::AbstractDraw::CreateLine
	// Returns:   int Size used
	// Notes:
	// -Size = 2
	//************************************
	int AbstractDraw::CreateLine(SHAPEVERTEX* Buffer, Vector2 Point1, Vector2 Point2, D3DCOLOR Color1, D3DCOLOR Color2)
	{
		if (Buffer)
		{
			Buffer[0].color = Color1;
			Buffer[0].rhw = 1.0f;
			Buffer[0].x = Point1.x;
			Buffer[0].y = Point1.y;
			Buffer[0].z = 0.0f;
			
			Buffer[1].color = Color2;
			Buffer[1].rhw = 1.0f;
			Buffer[1].x = Point2.x;
			Buffer[1].y = Point2.y;
			Buffer[1].z = 0.0f;
		}
		return SIZE_LINE;
	}

	//************************************
	// Method:    CreateMultiLine
	// Profit:	  Creates multiple Lines
	// FullName:  SD_Tools::AbstractDraw::CreateMultiLine
	// Returns:   int
	// Notes:
	// -Size = 2 * (NumberOfPoints-1)
	//************************************
	int AbstractDraw::CreateMultiLine(SHAPEVERTEX* Buffer, Vector2* Points, int NumberOfPoints, D3DCOLOR Color)
	{
		if (Buffer)
		{
			for (int i = 0; i < NumberOfPoints-1; i++)
			{
				CreateLine(Buffer+i*2, Points[i], Points[i+1], Color);
			}
		}
		return SIZE_LINE * (NumberOfPoints-1);
	}
	
	//************************************
	// Method:    CreateMultiLine
	// Profit:	  Creates multiple Lines
	// FullName:  SD_Tools::AbstractDraw::CreateMultiLine
	// Returns:   int
	// Notes:
	// -Size = 2 * (NumberOfPoints-1)
	//************************************
	int AbstractDraw::CreateMultiLine(SHAPEVERTEX* Buffer, Vector2* Points, int NumberOfPoints, D3DCOLOR* Colors)
	{
		if (Buffer)
		{
			for (int i = 0; i < NumberOfPoints-1; i++)
			{
				CreateLine(Buffer+i*2, Points[i], Points[i+1], Colors[i], Colors[i+1]);
			}
		}
		return SIZE_LINE * (NumberOfPoints-1);
	}

	//************************************
	// Method:    CreateOutlineTriangle
	// Profit:	  Creates 3 Lines in Triangle Shape
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineTriangle
	// Returns:   int
	// Notes:
	// -Size = 6
	//************************************
	int AbstractDraw::CreateOutlineTriangle(SHAPEVERTEX* Buffer, Vector2 Point1, Vector2 Point2, Vector2 Point3, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer += CreateLine(Buffer, Point1, Point2, Color);
			Buffer += CreateLine(Buffer, Point2, Point3, Color);
			CreateLine(Buffer, Point3, Point1, Color);
		}
		return SIZE_LINE * 3;
	}
	
	//************************************
	// Method:    CreateOutlineTriangle
	// Profit:	  Creates 3 Lines in Triangle Shape
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineTriangle
	// Returns:   int
	// Notes:
	// -Size = 6
	//************************************
	int AbstractDraw::CreateOutlineTriangle(SHAPEVERTEX* Buffer, Vector2 Point1, Vector2 Point2, Vector2 Point3, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3)
	{
		if (Buffer)
		{
			Buffer += CreateLine(Buffer, Point1, Point2, Color1, Color2);
			Buffer += CreateLine(Buffer, Point2, Point3, Color2, Color3);
			CreateLine(Buffer, Point3, Point1, Color3, Color1);
		}
		return SIZE_LINE * 3;
	}

	//************************************
	// Method:    CreateOutlineRectangle
	// Profit:	  Creates 4 Lines in Rectangle Shape
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineRectangle
	// Returns:   int
	// Notes:
	// -Size = 8
	//************************************
	int AbstractDraw::CreateOutlineRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer += CreateLine(Buffer, Vector2(Rect.x, Rect.y), Vector2(Rect.x+Rect.w, Rect.y), Color);
			Buffer += CreateLine(Buffer, Vector2(Rect.x+Rect.w, Rect.y), Vector2(Rect.x+Rect.w, Rect.y+Rect.h), Color);
			Buffer += CreateLine(Buffer, Vector2(Rect.x+Rect.w, Rect.y+Rect.h), Vector2(Rect.x, Rect.y+Rect.h), Color);
			CreateLine(Buffer, Vector2(Rect.x, Rect.y+Rect.h), Vector2(Rect.x, Rect.y), Color);
		}
		return SIZE_LINE * 4;
	}
	
	//************************************
	// Method:    CreateOutlineRectangle
	// Profit:	  Creates 4 Lines in Rectangle Shape
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineRectangle
	// Returns:   int
	// Notes:
	// -Size = 8
	//************************************
	int AbstractDraw::CreateOutlineRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4)
	{
		if (Buffer)
		{
			Buffer += CreateLine(Buffer, Vector2(Rect.x, Rect.y), Vector2(Rect.x+Rect.w, Rect.y), Color1, Color2);
			Buffer += CreateLine(Buffer, Vector2(Rect.x+Rect.w, Rect.y), Vector2(Rect.x+Rect.w, Rect.y+Rect.h), Color2, Color3);
			Buffer += CreateLine(Buffer, Vector2(Rect.x+Rect.w, Rect.y+Rect.h), Vector2(Rect.x, Rect.y+Rect.h), Color3, Color4);
			CreateLine(Buffer, Vector2(Rect.x, Rect.y+Rect.h), Vector2(Rect.x, Rect.y), Color4, Color1);
		}
		return SIZE_LINE * 4;
	}

	//************************************
	// Method:    CreateOutlineCone
	// Profit:	  Creates an OutlineCone
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineCone
	// Returns:   int
	// Notes:
	// -Size = variable
	//************************************
	int AbstractDraw::CreateOutlineCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color)
	{
		int retn;
		if (Buffer)
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else if (FloatNear(WidthAngle, 360.0f, 0.001f))
			{
				for (int i = 0; i < 360; i++)
				{
					Buffer += CreateLine(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color);
					StartAngle += 1.0f;
				}
				retn = SIZE_LINE * (int) (WidthAngle+0.5f);
			}
			else
			{
				Buffer += CreateLine(Buffer, Origin, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Color);
				int Steps = (int) (WidthAngle+0.5f);

				for (int i = 0; i < Steps; i++)
				{
					Buffer += CreateLine(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color);
					StartAngle += 1.0f;
				}

				CreateLine(Buffer, Origin, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Color);

				retn = SIZE_LINE * (int) (WidthAngle+0.5f) + 2;
			}
		}
		else
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else if (FloatNear(WidthAngle, 360.0f, 0.001f))
			{
				retn = SIZE_LINE * (int) (WidthAngle+0.5f);
			}
			else
			{
				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) + 2);
			}
		}
		return retn;
	}
	
	//************************************
	// Method:    CreateOutlineCone
	// Profit:	  Creates an OutlineCone
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineCone
	// Returns:   int
	// Notes:
	// -Size = variable
	//************************************
	int AbstractDraw::CreateOutlineOutCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color)
	{
		int retn;
		if (Buffer)
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				int Steps = (int) (WidthAngle+0.5f);

				for (int i = 0; i < Steps; i++)
				{
					Buffer += CreateLine(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color);
					StartAngle += 1.0f;
				}
				retn = SIZE_LINE * Steps;
			}
		}
		else
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				retn = SIZE_LINE * (int) (WidthAngle+0.5f);
			}
		}
		return retn;
	}
	
	//************************************
	// Method:    CreateOutlineCone
	// Profit:	  Creates an OutlineCone
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineCone
	// Returns:   int
	// Notes:
	// -Size = variable
	//************************************
	int AbstractDraw::CreateOutlineCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color1, D3DCOLOR Color2)
	{
		int retn;
		if (Buffer)
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else if (FloatNear(WidthAngle, 360.0f, 0.001f))
			{
				for (int i = 0; i < 360; i++)
				{
					Buffer += CreateLine(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color2);
					StartAngle += 1.0f;
				}
				retn = SIZE_LINE * (int) (WidthAngle+0.5f);
			}
			else
			{
				Buffer += CreateLine(Buffer, Origin, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Color1, Color2);
				int Steps = (int) (WidthAngle+0.5f);

				for (int i = 0; i < Steps; i++)
				{
					Buffer += CreateLine(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color2);
					StartAngle += 1.0f;
				}

				CreateLine(Buffer, Origin, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Color1, Color2);

				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) + 2);
			}
		}
		else
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else if (FloatNear(WidthAngle, 360.0f, 0.001f))
			{
				retn = SIZE_LINE * (int) (WidthAngle+0.5f);
			}
			else
			{
				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) + 2);
			}
		}
		return retn;
	}

	//************************************
	// Method:    CreateOutlineBorderCone
	// Profit:	  Creates only the Outside of the OutlineCone
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineBorderCone
	// Returns:   int
	// Notes:
	// -Size = variable
	//************************************
	int AbstractDraw::CreateOutlineBorderCone( SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, Vector2 Size, D3DCOLOR Color )
	{
		int retn;
		if (Buffer)
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else if (FloatNear(WidthAngle, 360.0f, 0.001f))
			{
				for (int i = 0; i < 360; i++)
				{
					Buffer += CreateLine(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color);
					Buffer += CreateLine(Buffer, Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle+1.0f)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle+1.0f))), Color);
					StartAngle += 1.0f;
				}
				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) * 2);
			}
			else
			{
				Buffer += CreateLine(Buffer, Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Color);
				int Steps = (int) (WidthAngle+0.5f);

				for (int i = 0; i < Steps; i++)
				{
					Buffer += CreateLine(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color);
					Buffer += CreateLine(Buffer, Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle+1.0f)), Origin.y - (Radius.y - Size.x)*cosf(DegToRad(StartAngle+1.0f))), Color);
					StartAngle += 1.0f;
				}

				CreateLine(Buffer, Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Color);

				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) * 2 + 2);
			}
		}
		else
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else if (FloatNear(WidthAngle, 360.0f, 0.001f))
			{
				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) * 2);
			}
			else
			{
				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) * 2 + 2);
			}
		}
		return retn;
	}

	//************************************
	// Method:    CreateOutlineBorderCone
	// Profit:	  Creates only the Outside of the OutlineCone
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineBorderCone
	// Returns:   int
	// Notes:
	// -Size = variable
	//************************************
	int AbstractDraw::CreateOutlineBorderCone( SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, Vector2 Size, D3DCOLOR Color1, D3DCOLOR Color2 )
	{
		int retn;
		if (Buffer)
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else if (FloatNear(WidthAngle, 360.0f, 0.001f))
			{
				for (int i = 0; i < 360; i++)
				{
					Buffer += CreateLine(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color2);
					Buffer += CreateLine(Buffer, Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle+1.0f)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle+1.0f))), Color1);
					StartAngle += 1.0f;
				}
				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) * 2);
			}
			else
			{
				Buffer += CreateLine(Buffer, Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Color1, Color2);
				int Steps = (int) (WidthAngle+0.5f);

				for (int i = 0; i < Steps; i++)
				{
					Buffer += CreateLine(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color2);
					Buffer += CreateLine(Buffer, Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle+1.0f)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle+1.0f))), Color1);
					StartAngle += 1.0f;
				}

				CreateLine(Buffer, Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Color1, Color2);

				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) * 2 + 2);
			}
		}
		else
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else if (FloatNear(WidthAngle, 360.0f, 0.001f))
			{
				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) * 2);
			}
			else
			{
				retn = SIZE_LINE * ((int) (WidthAngle+0.5f) * 2 + 2);
			}
		}
		return retn;
	}

	//************************************
	// Method:    CreateOutlineRoundedRectangle
	// Profit:	  Creates an OutlineRoundedRectangle
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineRoundedRectangle
	// Returns:   int
	// Notes:
	// -Size = 2 * (24*92)
	//************************************
	int AbstractDraw::CreateOutlineRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y+OutSize.y, Rect.w-OutSize.x*2, Rect.h-OutSize.y*2), Color); // Middle

			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y, Rect.w-OutSize.x*2, OutSize.y), Color); // toprect
			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y, OutSize.x, Rect.h-OutSize.y*2), Color); // right
			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y, Rect.w-OutSize.x*2, OutSize.y), Color); // bot
			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x, Rect.y+OutSize.y, OutSize.x, Rect.h-OutSize.y*2), Color); // left
			
			Buffer += CreateOutlineCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+OutSize.y), OutSize, 270.0f, 90.0f, Color); // topleft
			Buffer += CreateOutlineCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y), OutSize, 0.0f, 90.0f, Color); // topright
			Buffer += CreateOutlineCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 90.0f, 90.0f, Color); // botright
			CreateOutlineCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 180.0f, 90.0f, Color); // botleft
		}
		return SIZE_LINE * (20 + 4* 92);
	}
	
	//************************************
	// Method:    CreateOutlineOutRoundedRectangle
	// Profit:	  Creates an OutlineRoundedRectangle
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineOutRoundedRectangle
	// Returns:   int
	// Notes:
	// -Size = 2 * (4 + 4 * 90)
	//************************************
	int AbstractDraw::CreateOutlineOutRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer += CreateLine(Buffer, Vector2(Rect.x+OutSize.x, Rect.y), Vector2(Rect.x+Rect.w-OutSize.x, Rect.y), Color);
			Buffer += CreateLine(Buffer, Vector2(Rect.x+Rect.w, Rect.y+OutSize.y), Vector2(Rect.x+Rect.w, Rect.y+Rect.h-OutSize.y), Color);
			Buffer += CreateLine(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+Rect.h), Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+Rect.h), Color);
			Buffer += CreateLine(Buffer, Vector2(Rect.x, Rect.y+OutSize.y), Vector2(Rect.x, Rect.y+Rect.h-OutSize.y), Color);

			Buffer += CreateOutlineOutCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+OutSize.y), OutSize, 270.0f, 90.0f, Color); // topleft
			Buffer += CreateOutlineOutCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y), OutSize, 0.0f, 90.0f, Color); // topright
			Buffer += CreateOutlineOutCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 90.0f, 90.0f, Color); // botright
			CreateOutlineOutCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 180.0f, 90.0f, Color); // botleft
		}
		return SIZE_LINE * (4 + 4 * 90);
	}

	//************************************
	// Method:    CreateOutlineRoundedRectangle
	// Profit:	  Creates an OutlineRoundedRectangle
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineRoundedRectangle
	// Returns:   int
	// Notes:
	// -Size = 2 * (20 + 4 * 92)
	//************************************
	int AbstractDraw::CreateOutlineRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4, D3DCOLOR Color5, D3DCOLOR Color6, D3DCOLOR Color7, D3DCOLOR Color8)
	{
		if (Buffer)
		{
			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y+OutSize.y, Rect.w-OutSize.x*2, Rect.h-OutSize.y*2), Color1, Color3, Color5, Color7); // Middle

			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y, Rect.w-OutSize.x*2, OutSize.y), Color2, Color4, Color3, Color1); // toprect
			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y, OutSize.x, Rect.h-OutSize.y*2), Color3, Color4, Color6, Color5); // right
			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y, Rect.w-OutSize.x*2, OutSize.y), Color7, Color5, Color6, Color8); // bot
			Buffer += CreateOutlineRectangle(Buffer, Rectangle2(Rect.x, Rect.y+OutSize.y, OutSize.x, Rect.h-OutSize.y*2), Color2, Color1, Color7, Color8); // left
			
			Buffer += CreateOutlineCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+OutSize.y), OutSize, 270.0f, 90.0f,  Color1, Color2); // topleft
			Buffer += CreateOutlineCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y), OutSize, 0.0f, 90.0f, Color3, Color4); // topright
			Buffer += CreateOutlineCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 90.0f, 90.0f, Color5, Color6); // botright
			CreateOutlineCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 180.0f, 90.0f, Color7, Color8); // botleft
		}
		return SIZE_LINE * (20 + 4*92);
	}
	
	//************************************
	// Method:    CreateOutlineOutRoundedRectangle
	// Profit:	  Creates an OutlineRoundedRectangle
	// FullName:  SD_Tools::AbstractDraw::CreateOutlineOutRoundedRectangle
	// Returns:   int
	// Notes:
	// -Size = 2 * (4 + 4*90)
	//************************************
	int AbstractDraw::CreateOutlineOutRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4)
	{
		if (Buffer)
		{
			Buffer += CreateLine(Buffer, Vector2(Rect.x+OutSize.x, Rect.y), Vector2(Rect.x+Rect.w-OutSize.x, Rect.y), Color1, Color2);
			Buffer += CreateLine(Buffer, Vector2(Rect.x+Rect.w, Rect.y+OutSize.y), Vector2(Rect.x+Rect.w, Rect.y+Rect.h-OutSize.y), Color2, Color3);
			Buffer += CreateLine(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+Rect.h), Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+Rect.h), Color4, Color3);
			Buffer += CreateLine(Buffer, Vector2(Rect.x, Rect.y+OutSize.y), Vector2(Rect.x, Rect.y+Rect.h-OutSize.y), Color4, Color1);

			Buffer += CreateOutlineOutCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+OutSize.y), OutSize, 270.0f, 90.0f,  Color1); // topleft
			Buffer += CreateOutlineOutCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y), OutSize, 0.0f, 90.0f, Color2); // topright
			Buffer += CreateOutlineOutCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 90.0f, 90.0f, Color3); // botright
			CreateOutlineOutCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 180.0f, 90.0f, Color4); // botleft
		}
		return SIZE_LINE * (4 + 4 * 90);
	}

	//************************************
	// Method:    CreateTriangle
	// Profit:	  Creates a Triangle
	// FullName:  SD_Tools::AbstractDraw::CreateTriangle
	// Returns:   int
	// Notes:
	// -Size = 3
	//************************************
	int AbstractDraw::CreateTriangle(SHAPEVERTEX* Buffer, Vector2 Position1, Vector2 Position2, Vector2 Position3, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer[0].color = Color;
			Buffer[0].rhw = 1.0f;
			Buffer[0].x = Position1.x;
			Buffer[0].y = Position1.y;
			Buffer[0].z = 0.0f;
			
			Buffer[1].color = Color;
			Buffer[1].rhw = 1.0f;
			Buffer[1].x = Position2.x;
			Buffer[1].y = Position2.y;
			Buffer[1].z = 0.0f;
			
			Buffer[2].color = Color;
			Buffer[2].rhw = 1.0f;
			Buffer[2].x = Position3.x;
			Buffer[2].y = Position3.y;
			Buffer[2].z = 0.0f;
		}
		return SIZE_TRIANGLE;
	}

	//************************************
	// Method:    CreateTriangle
	// Profit:	  Creates a Triangle
	// FullName:  SD_Tools::AbstractDraw::CreateTriangle
	// Returns:   int
	// Notes:
	// -Size = 3
	//************************************
	int AbstractDraw::CreateTriangle(SHAPEVERTEX* Buffer, Vector2 Position1, Vector2 Position2, Vector2 Position3, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3)
	{
		if (Buffer)
		{
			Buffer[0].color = Color1;
			Buffer[0].rhw = 1.0f;
			Buffer[0].x = Position1.x;
			Buffer[0].y = Position1.y;
			Buffer[0].z = 0.0f;
			
			Buffer[1].color = Color2;
			Buffer[1].rhw = 1.0f;
			Buffer[1].x = Position2.x;
			Buffer[1].y = Position2.y;
			Buffer[1].z = 0.0f;
			
			Buffer[2].color = Color3;
			Buffer[2].rhw = 1.0f;
			Buffer[2].x = Position3.x;
			Buffer[2].y = Position3.y;
			Buffer[2].z = 0.0f;
		}
		return SIZE_TRIANGLE;
	}


	//************************************
	// Method:    CreateQuad
	// Profit:	  Creates a Quad
	// FullName:  SD_Tools::AbstractDraw::CreateQuad
	// Returns:   int
	// Notes:
	// -Size = 6
	//************************************
	int AbstractDraw::CreateQuad(SHAPEVERTEX* Buffer, Vector2 Position1, Vector2 Position2, Vector2 Position3, Vector2 Position4, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer += CreateTriangle(Buffer, Position1, Position2, Position4, Color);
			CreateTriangle(Buffer, Position4, Position2, Position3, Color);
		}
		return SIZE_QUAD;
	}

	//************************************
	// Method:    CreateQuad
	// Profit:	  Creates a Quad
	// FullName:  SD_Tools::AbstractDraw::CreateQuad
	// Returns:   int
	// Notes:
	// -Size = 6
	//************************************
	int AbstractDraw::CreateQuad(SHAPEVERTEX* Buffer, Vector2 Position1, Vector2 Position2, Vector2 Position3, Vector2 Position4, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4)
	{
		if (Buffer)
		{
			Buffer += CreateTriangle(Buffer, Position1, Position2, Position4, Color1, Color2, Color4);
			CreateTriangle(Buffer, Position4, Position2, Position3, Color4, Color2, Color3);
		}
		return SIZE_QUAD;
	}

	//************************************
	// Method:    CreateRectangle
	// Profit:	  Creates a Rectangle
	// FullName:  SD_Tools::AbstractDraw::CreateRectangle
	// Returns:   int
	// Notes:
	// -Size = 6
	//************************************
	int AbstractDraw::CreateRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer += CreateTriangle(Buffer, Vector2(Rect.x, Rect.y), Vector2(Rect.x+Rect.w, Rect.y), Vector2(Rect.x, Rect.y+Rect.h), Color);
			CreateTriangle(Buffer, Vector2(Rect.x, Rect.y+Rect.h), Vector2(Rect.x+Rect.w, Rect.y), Vector2(Rect.x+Rect.w, Rect.y+Rect.h), Color);
		}
		return SIZE_RECT;
	}

	//************************************
	// Method:    CreateRectangle
	// Profit:	  Creates a Rectangle
	// FullName:  SD_Tools::AbstractDraw::CreateRectangle
	// Returns:   int
	// Notes:
	// -Size = 6
	//************************************
	int AbstractDraw::CreateRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4)
	{
		if (Buffer)
		{
			Buffer += CreateTriangle(Buffer, Vector2(Rect.x, Rect.y), Vector2(Rect.x+Rect.w, Rect.y), Vector2(Rect.x, Rect.y+Rect.h), Color1, Color2, Color4);
			CreateTriangle(Buffer, Vector2(Rect.x, Rect.y+Rect.h), Vector2(Rect.x+Rect.w, Rect.y), Vector2(Rect.x+Rect.w, Rect.y+Rect.h), Color4, Color2, Color3);
		}
		return SIZE_RECT;
	}

	//************************************
	// Method:    CreateMultiShape
	// Profit:	  Creates a MultiShape
	// FullName:  SD_Tools::AbstractDraw::CreateMultiShape
	// Returns:   int
	// Notes:
	// -Size = 3 * (NumberOfPoints-3)
	// -Interpreted as TriangleList
	//************************************
	int AbstractDraw::CreateMultiShape(SHAPEVERTEX* Buffer, Vector2* Points, int NumberOfPoints, D3DCOLOR Color)
	{
		if (Buffer)
		{
			for (int i = 0; i < NumberOfPoints-3; i++)
			{
				Buffer += CreateTriangle(Buffer, Points[i], Points[i+1], Points[i+2], Color);
			}
		}
		return SIZE_TRIANGLE * (NumberOfPoints-3);
	}
	
	//************************************
	// Method:    CreateMultiShape
	// Profit:	  Creates a MultiShape
	// FullName:  SD_Tools::AbstractDraw::CreateMultiShape
	// Returns:   int
	// Notes:
	// -Size = 3 * (NumberOfPoints-3)
	// -Interpreted as TriangleList
	//************************************
	int AbstractDraw::CreateMultiShape(SHAPEVERTEX* Buffer, Vector2* Points, int NumberOfPoints, D3DCOLOR* Colors)
	{
		if (Buffer)
		{
			for (int i = 0; i < NumberOfPoints-3; i++)
			{
				Buffer += CreateTriangle(Buffer, Points[i], Points[i+1], Points[i+2], Colors[i], Colors[i+1], Colors[i+2]);
			}
		}
		return SIZE_TRIANGLE * (NumberOfPoints-3);
	}

	//************************************
	// Method:    CreateCone
	// Profit:	  Creates a Cone
	// FullName:  SD_Tools::AbstractDraw::CreateCone
	// Returns:   int
	// Notes:
	// -variable
	//************************************
	int AbstractDraw::CreateCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color)
	{
		int retn;
		if (Buffer)
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				int Steps = (int) (WidthAngle+0.5f);

				for (int i = 0; i < Steps; i++)
				{
					Buffer += CreateTriangle(Buffer, Origin, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color);
					StartAngle += 1.0f;
				}
				retn = SIZE_TRIANGLE * Steps;
			}
		}
		else
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				retn = SIZE_TRIANGLE * (int) (WidthAngle+0.5f);
			}
		}
		return retn;
	}

	//************************************
	// Method:    CreateCone
	// Profit:	  Creates a Cone
	// FullName:  SD_Tools::AbstractDraw::CreateCone
	// Returns:   int
	// Notes:
	// -Size = variable
	//************************************
	int AbstractDraw::CreateCone(SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, D3DCOLOR Color1, D3DCOLOR Color2)
	{
		int retn;
		if (Buffer)
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				int Steps = (int) (WidthAngle+0.5f);

				for (int i = 0; i < Steps; i++)
				{
					Buffer += CreateTriangle(Buffer, Origin, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Color1, Color2, Color2);
					StartAngle += 1.0f;
				}
				retn = SIZE_TRIANGLE * Steps;
			}
		}
		else
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				retn = SIZE_TRIANGLE * (int) (WidthAngle+0.5f);
			}
		}
		return retn;
	}

	//************************************
	// Method:    CreateBorderCone
	// Profit:	  Creates a ConePart
	// FullName:  SD_Tools::AbstractDraw::CreateBorderCone
	// Returns:   int
	// Notes:
	// -Size = variable
	//************************************
	int AbstractDraw::CreateBorderCone( SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, Vector2 Size, D3DCOLOR Color )
	{
		int retn = 0;
		if (Buffer)
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				int Steps = (int) (WidthAngle+0.5f);
				for (int i = 0; i < Steps; i++)
				{
					Buffer += CreateQuad(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle+1.0f)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle+1.0f))), Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Color);
					StartAngle += 1.0f;
				}
				return SIZE_QUAD * Steps;
			}

		}
		else
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				retn = SIZE_QUAD * (int) (WidthAngle+0.5f);
			}
		}
		return retn;
	}

	//************************************
	// Method:    CreateBorderCone
	// Profit:	  Creates a ConePart
	// FullName:  SD_Tools::AbstractDraw::CreateBorderCone
	// Returns:   int
	// Notes:
	// -Size = variable
	//************************************
	int AbstractDraw::CreateBorderCone( SHAPEVERTEX* Buffer, Vector2 Origin, Vector2 Radius, float StartAngle, float WidthAngle, Vector2 Size, D3DCOLOR Color1, D3DCOLOR Color2 )
	{
		int retn = 0;
		if (Buffer)
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				int Steps = (int) (WidthAngle+0.5f);
				for (int i = 0; i < Steps; i++)
				{
					Buffer += CreateQuad(Buffer, Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle)), Origin.y - Radius.y*cosf(DegToRad(StartAngle))), Vector2(Origin.x + Radius.x*sinf(DegToRad(StartAngle+1.0f)), Origin.y - Radius.y*cosf(DegToRad(StartAngle+1.0f))), Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle+1.0f)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle+1.0f))), Vector2(Origin.x + (Radius.x - Size.x)*sinf(DegToRad(StartAngle)), Origin.y - (Radius.y - Size.y)*cosf(DegToRad(StartAngle))), Color2, Color2, Color1, Color1);
					StartAngle += 1.0f;
				}
				return SIZE_QUAD * Steps;
			}

		}
		else
		{
			if (FloatNear(WidthAngle, 0.0f, 0.001f))
			{
				retn = SIZE_NULL;
			}
			else
			{
				retn = SIZE_QUAD * (int) (WidthAngle+0.5f);
			}
		}
		return retn;
	}

	//************************************
	// Method:    CreateRoundedRectangle
	// Profit:	  Creates a Rounded Rectangle
	// FullName:  SD_Tools::AbstractDraw::CreateRoundedRectangle
	// Returns:   int
	// Notes:
	// -Size = 3 * (10 + 4*90)
	//************************************
	int AbstractDraw::CreateRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color)
	{
		if (Buffer)
		{
			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y+OutSize.y, Rect.w-OutSize.x*2, Rect.h-OutSize.y*2), Color);

			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y, Rect.w-OutSize.x*2, OutSize.y), Color); // toprect
			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y, OutSize.x, Rect.h-OutSize.y*2), Color); // right
			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y, Rect.w-OutSize.x*2, OutSize.y), Color); // bot
			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x, Rect.y+OutSize.y, OutSize.x, Rect.h-OutSize.y*2), Color); // left

			Buffer += CreateCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+OutSize.y), OutSize, 270.0f, 90.0f, Color); // topleft
			Buffer += CreateCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y), OutSize, 0.0f, 90.0f, Color); // topright
			Buffer += CreateCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 90.0f, 90.0f, Color); // botright
			CreateCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 180.0f, 90.0f, Color); // botleft
		}
		return SIZE_TRIANGLE * (10 + 4 * 90);
	}

	//************************************
	// Method:    CreateRoundedRectangle
	// Profit:	  Creates a Rounded Rectangle
	// FullName:  SD_Tools::AbstractDraw::CreateRoundedRectangle
	// Returns:   int
	// Notes:
	// -Size = 3 * (10 + 4*90)
	//************************************
	int AbstractDraw::CreateRoundedRectangle(SHAPEVERTEX* Buffer, Rectangle2 Rect, Vector2 OutSize, D3DCOLOR Color1, D3DCOLOR Color2, D3DCOLOR Color3, D3DCOLOR Color4, D3DCOLOR Color5, D3DCOLOR Color6, D3DCOLOR Color7, D3DCOLOR Color8)
	{
		if (Buffer)
		{
			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y+OutSize.y, Rect.w-OutSize.x*2, Rect.h-OutSize.y*2), Color1, Color3, Color5, Color7); // Middle

			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y, Rect.w-OutSize.x*2, OutSize.y), Color2, Color4, Color3, Color1); // toprect
			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y, OutSize.x, Rect.h-OutSize.y*2), Color3, Color4, Color6, Color5); // right
			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y, Rect.w-OutSize.x*2, OutSize.y), Color7, Color5, Color6, Color8); // bot
			Buffer += CreateRectangle(Buffer, Rectangle2(Rect.x, Rect.y+OutSize.y, OutSize.x, Rect.h-OutSize.y*2), Color2, Color1, Color7, Color8); // left

			Buffer += CreateCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+OutSize.y), OutSize, 270.0f, 90.0f,  Color1, Color2); // topleft
			Buffer += CreateCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+OutSize.y), OutSize, 0.0f, 90.0f, Color3, Color4); // topright
			Buffer += CreateCone(Buffer, Vector2(Rect.x+Rect.w-OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 90.0f, 90.0f, Color5, Color6); // botright
			CreateCone(Buffer, Vector2(Rect.x+OutSize.x, Rect.y+Rect.h-OutSize.y), OutSize, 180.0f, 90.0f, Color7, Color8); // botleft
		}
		return SIZE_TRIANGLE * (10 + 4 * 90);
	}

	//************************************
	// Method:    MoveShapeBufferRelative
	// Profit:	  Moves ShapeVertices Relative
	// FullName:  SD_Tools::AbstractDraw::MoveShapeBufferRelative
	// Returns:   void
	// Notes:
	// -Adds Direction on every Vertex
	//************************************
	void AbstractDraw::MoveShapeBufferRelative(SHAPEVERTEX* Buffer, Vector2 Direction, int NumberOfVertices)
	{
		for (int i = 0; i < NumberOfVertices; i++)
		{
			Buffer[i].x += Direction.x;
			Buffer[i].y += Direction.y;
		}
	}

	//************************************
	// Method:    MoveShapeBufferAbsolute
	// Profit:	  Moves ShapeVertices Absolute by first Vertex
	// FullName:  SD_Tools::AbstractDraw::MoveShapeBufferAbsolute
	// Returns:   void
	// Notes:
	// -Adds Point - FirstVertex on every Vertex
	//************************************
	void AbstractDraw::MoveShapeBufferAbsolute(SHAPEVERTEX* Buffer, Vector2 Point, int NumberOfVertices)
	{
		Point.x -= Buffer[0].x;
		Point.y -= Buffer[0].y;
		MoveShapeBufferRelative(Buffer, Point, NumberOfVertices);
	}

	//************************************
	// Method:    MoveTextureBufferRelative
	// Profit:	  Moves TextureVertices Relative
	// FullName:  SD_Tools::AbstractDraw::MoveTextureBufferRelative
	// Returns:   void
	// Notes:
	// -Adds Direction on every Vertex
	//************************************
	void AbstractDraw::MoveTextureBufferRelative(TEXVERTEX* Buffer, Vector2 Direction, int NumberOfVertices)
	{
		for (int i = 0; i < NumberOfVertices; i++)
		{
			Buffer[i].x += Direction.x;
			Buffer[i].y += Direction.y;
		}
	}

	//************************************
	// Method:    MoveTextureBufferAbsolute
	// Profit:	  Moves TextureVertices Absolute by first Vertex
	// FullName:  SD_Tools::AbstractDraw::MoveTextureBufferAbsolute
	// Returns:   void
	// Notes:
	// -Adds (Point - FirstVertex) on every Vertex
	//************************************
	void AbstractDraw::MoveTextureBufferAbsolute(TEXVERTEX* Buffer, Vector2 Point, int NumberOfVertices)
	{
		Point.x -= Buffer[0].x;
		Point.y -= Buffer[0].y;
		MoveTextureBufferRelative(Buffer, Point, NumberOfVertices);
	}

	//************************************
	// Method:    CreateSprite
	// Profit:	  Creates a Sprite
	// FullName:  SD_Tools::AbstractDraw::CreateSprite
	// Returns:   ID3DXSprite* NULL if failed
	// Notes:
	// -returns NULL upon failure
	//************************************
	HRESULT AbstractDraw::CreateSprite( IDirect3DDevice9* Device, ID3DXSprite** OutSprite )
	{
		return D3DXCreateSprite(Device, OutSprite);
	}

	//************************************
	// Method:    BeginSprite
	// Profit:	  Begins a Sprite rendering
	// FullName:  SD_Tools::AbstractDraw::BeginSprite
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Sprite::Begin called with "D3DXSPRITE_ALPHABLEND" which is required for D3DXFont::DrawText
	// -Must be called before a call to DrawText
	//************************************
	HRESULT AbstractDraw::BeginSprite( ID3DXSprite* Sprite )
	{
		return Sprite->Begin(D3DXSPRITE_ALPHABLEND);
	}

	//************************************
	// Method:    EndSprite
	// Profit:	  Ends the Sprite rendering
	// FullName:  SD_Tools::AbstractDraw::EndSprite
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Sprite::End
	//************************************
	HRESULT AbstractDraw::EndSprite( ID3DXSprite* Sprite )
	{
		return Sprite->End();
	}

	//************************************
	// Method:    SpriteResetA
	// Profit:	  Calls OnLostDevice
	// FullName:  SD_Tools::AbstractDraw::SpriteResetA
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Sprite::OnLostDevice
	// -Must be called before a Device::Reset() call
	//************************************
	HRESULT AbstractDraw::SpriteResetA( ID3DXSprite* Sprite )
	{
		return Sprite->OnLostDevice();
	}

	//************************************
	// Method:    SpriteResetB
	// Profit:	  Calls OnResetDevice
	// FullName:  SD_Tools::AbstractDraw::SpriteResetB
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Sprite::OnResetDevice
	// -Must be called after a Device::Reset() call
	//************************************
	HRESULT AbstractDraw::SpriteResetB( ID3DXSprite* Sprite )
	{
		return Sprite->OnResetDevice();
	}

	//************************************
	// Method:    DrawText
	// Profit:	  Draws Text (quite obvious, huh?)
	// FullName:  SD_Tools::AbstractDraw::DrawText
	// Returns:   int
	// Notes:
	// -Sprite might be NULL - however if you draw several texts, you should stick to sprites - which are also implemented in this lib
	// -Returns Font->DrawText(...)
	//************************************
	int AbstractDraw::DrawText(ID3DXFont* Font, ID3DXSprite* Sprite, Vector2 Point, D3DCOLOR Color, DrawTextType Type, char* text)
	{
		RECT FontRect = {0};
		Font->DrawTextA(NULL, text, -1, &FontRect, DT_CALCRECT, Color);
		switch (Type)
		{
			case SDDT_NORMAL:
				{
					FontRect.right += (LONG) Point.x;
					FontRect.left += (LONG) Point.x;
					FontRect.bottom += (LONG) Point.y;
					FontRect.top += (LONG) Point.y;
					break;
				}
			case SDDT_VCENTER:
				{
					long left = FontRect.left - FontRect.right;
					long bot = FontRect.bottom - FontRect.top;
					long right = (long) Point.x;
					long top = (long) Point.y;
					right -= left/2;
					left += right;
					top -= bot/2;
					bot += top;

					FontRect.right = right;
					FontRect.left = left;
					//FontRect.bottom = bot;
					//FontRect.top = top;
					FontRect.bottom += (LONG) Point.y;
					FontRect.top += (LONG) Point.y;
					break;

				}
			case SDDT_HCENTER:
				{
					long left = FontRect.left - FontRect.right;
					long bot = FontRect.bottom - FontRect.top;
					long right = (long) Point.x;
					long top = (long) Point.y;
					right -= left/2;
					left += right;
					top -= bot/2;
					bot += top;

					//FontRect.right = right;
					//FontRect.left = left;
					
					FontRect.right = right;
					FontRect.left = left;
					FontRect.bottom = bot;
					FontRect.top = top;
					break;

				}
			case SDDT_CENTER:
				{
					long left = FontRect.left - FontRect.right;
					long bot = FontRect.bottom - FontRect.top;
					long right = (long) Point.x;
					long top = (long) Point.y;
					right -= left/2;
					left += right;
					top -= bot/2;
					bot += top;

					FontRect.right = right;
					FontRect.left = left;
					FontRect.bottom = bot;
					FontRect.top = top;
					break;
				}
		}
		return Font->DrawTextA(Sprite, text, -1, &FontRect, DT_NOCLIP, Color);
	}

	//************************************
	// Method:    DrawText
	// Profit:	  Draws Text
	// FullName:  SD_Tools::AbstractDraw::DrawText
	// Returns:   int
	// Notes:
	// -Sprite might be NULL - however if you draw several texts, you should stick to sprites - which are also implemented in this lib
	//************************************
	int AbstractDraw::DrawText(ID3DXFont* Font, ID3DXSprite* Sprite, Vector2 Point, D3DCOLOR Color, DrawTextType Type, wchar_t* text)
	{
		RECT FontRect = {0};
		Font->DrawTextW(NULL, text, -1, &FontRect, DT_CALCRECT, Color);
		switch (Type)
		{
			case SDDT_NORMAL:
				{
					FontRect.right += (LONG) Point.x;
					FontRect.left += (LONG) Point.x;
					FontRect.bottom += (LONG) Point.y;
					FontRect.top += (LONG) Point.y;
					break;
				}
			case SDDT_VCENTER:
				{
					long left = FontRect.left - FontRect.right;
					long bot = FontRect.bottom - FontRect.top;
					long right = (long) Point.x;
					long top = (long) Point.y;
					right -= left/2;
					left += right;
					top -= bot/2;
					bot += top;

					FontRect.right = right;
					FontRect.left = left;
					//FontRect.bottom = bot;
					//FontRect.top = top;
					FontRect.bottom += (LONG) Point.y;
					FontRect.top += (LONG) Point.y;
					break;

				}
			case SDDT_HCENTER:
				{
					long left = FontRect.left - FontRect.right;
					long bot = FontRect.bottom - FontRect.top;
					long right = (long) Point.x;
					long top = (long) Point.y;
					right -= left/2;
					left += right;
					top -= bot/2;
					bot += top;

					//FontRect.right = right;
					//FontRect.left = left;
					
					FontRect.right = right;
					FontRect.left = left;
					FontRect.bottom = bot;
					FontRect.top = top;
					break;

				}
			case SDDT_CENTER:
				{
					long left = FontRect.left - FontRect.right;
					long bot = FontRect.bottom - FontRect.top;
					long right = (long) Point.x;
					long top = (long) Point.y;
					right -= left/2;
					left += right;
					top -= bot/2;
					bot += top;

					FontRect.right = right;
					FontRect.left = left;
					FontRect.bottom = bot;
					FontRect.top = top;
					break;
				}
		}
		return Font->DrawTextW(Sprite, text, -1, &FontRect, DT_NOCLIP, Color);
	}

	//************************************
	// Method:    DrawTextFormat
	// Profit:	  Draws a TextFormat with up to 512 characters
	// FullName:  SD_Tools::AbstractDraw::DrawTextFormat
	// Returns:   int
	// Notes:
	// -Sprite might be NULL - however if you draw several texts, you should stick to sprites - which are also implemented in this lib
	// -Returns Font->DrawText(...)
	// -The behavior if the format exceeds 512 characters is UNDEFINED
	//************************************
	int AbstractDraw::DrawTextFormat(ID3DXFont* Font, ID3DXSprite* Sprite, Vector2 Point, D3DCOLOR Color, DrawTextType Type, char* text, ...)
	{
		char Buffer[512];
		
        va_list args;
        va_start(args, text);

		vsprintf(Buffer, text, args);

		va_end(args);

		return AbstractDraw::DrawText(Font, Sprite, Point, Color, Type, Buffer);
	}

	//************************************
	// Method:    DrawTextFormat
	// Profit:	  Draws a TextFormat with up to 512 characters
	// FullName:  SD_Tools::AbstractDraw::DrawTextFormat
	// Returns:   int
	// Notes:
	// -Sprite might be NULL - however if you draw several texts, you should stick to sprites - which are also implemented in this lib
	// -Returns Font->DrawText(...)
	// -The behavior if the format exceeds 512 characters is UNDEFINED
	//************************************
	int AbstractDraw::DrawTextFormat(ID3DXFont* Font, ID3DXSprite* Sprite, Vector2 Point, D3DCOLOR Color, DrawTextType Type, wchar_t* text, ...)
	{
		wchar_t Buffer[512];
		
        va_list args;
        va_start(args, text);

		vswprintf(Buffer, text, args);

		va_end(args);

		return AbstractDraw::DrawText(Font, Sprite, Point, Color, Type, Buffer);
	}


	//************************************
	// Method:    DrawText
	// Profit:	  Draws Text
	// FullName:  SD_Tools::AbstractDraw::DrawText
	// Returns:   int
	// Notes:
	// -Sprite might be NULL - however if you draw several texts, you should stick to sprites - which are also implemented in this lib
	// -Returns Font->DrawText(...)
	//************************************
	int AbstractDraw::DrawText(ID3DXFont* Font, ID3DXSprite* Sprite, Rectangle2 Rect, D3DCOLOR Color, DrawTextType Type, char* text)
	{
		switch (Type)
		{
			case SDDT_NORMAL:
				{
					return AbstractDraw::DrawText(Font, Sprite, Vector2(Rect.x, Rect.y), Color, Type, text);
				}
			case SDDT_VCENTER:
				{
					return AbstractDraw::DrawText(Font, Sprite, Vector2(Rect.x, Rect.y+Rect.h/2), Color, Type, text);
				}
			case SDDT_HCENTER:
				{
					return AbstractDraw::DrawText(Font, Sprite, Vector2(Rect.x+Rect.w/2, Rect.y), Color, Type, text);
				}
			case SDDT_CENTER:
				{
					return AbstractDraw::DrawText(Font, Sprite, Vector2(Rect.x+Rect.w/2, Rect.y+Rect.h/2), Color, Type, text);
				}
		}
		return 0;
	}

	//************************************
	// Method:    DrawText
	// Profit:	  Draws Text
	// FullName:  SD_Tools::AbstractDraw::DrawText
	// Returns:   int
	// Notes:
	// -Sprite might be NULL - however if you draw several texts, you should stick to sprites - which are also implemented in this lib
	// -Returns Font->DrawText(...)
	//************************************
	int AbstractDraw::DrawText(ID3DXFont* Font, ID3DXSprite* Sprite, Rectangle2 Rect, D3DCOLOR Color, DrawTextType Type, wchar_t* text)
	{
		switch (Type)
		{
			case SDDT_NORMAL:
				{
					return AbstractDraw::DrawText(Font, Sprite, Vector2(Rect.x, Rect.y), Color, Type, text);
				}
			case SDDT_VCENTER:
				{
					return AbstractDraw::DrawText(Font, Sprite, Vector2(Rect.x, Rect.y+Rect.h/2), Color, Type, text);
				}
			case SDDT_HCENTER:
				{
					return AbstractDraw::DrawText(Font, Sprite, Vector2(Rect.x+Rect.w/2, Rect.y), Color, Type, text);
				}
			case SDDT_CENTER:
				{
					return AbstractDraw::DrawText(Font, Sprite, Vector2(Rect.x+Rect.w/2, Rect.y+Rect.h/2), Color, Type, text);
				}
		}
		return 0;
	}

	//************************************
	// Method:    DrawTextFormat
	// Profit:	  Draws a TextFormat with up to 512 characters
	// FullName:  SD_Tools::AbstractDraw::DrawTextFormat
	// Returns:   int
	// Notes:
	// -Sprite might be NULL - however if you draw several texts, you should stick to sprites - which are also implemented in this lib
	// -Returns Font->DrawText(...)
	// -The behavior if the format exceeds 512 characters is UNDEFINED
	//************************************
	int AbstractDraw::DrawTextFormat(ID3DXFont* Font, ID3DXSprite* Sprite, Rectangle2 Rect, D3DCOLOR Color, DrawTextType Type, char* text, ...)
	{
		char Buffer[512];
		
        va_list args;
        va_start(args, text);

		vsprintf(Buffer, text, args);

		va_end(args);

		return AbstractDraw::DrawText(Font, Sprite, Rect, Color, Type, Buffer);
	}

	//************************************
	// Method:    DrawTextFormat
	// Profit:	  Draws a TextFormat with up to 512 characters
	// FullName:  SD_Tools::AbstractDraw::DrawTextFormat
	// Returns:   int
	// Notes:
	// -Sprite might be NULL - however if you draw several texts, you should stick to sprites - which are also implemented in this lib
	// -Returns Font->DrawText(...)
	// -The behavior if the format exceeds 512 characters is UNDEFINED
	//************************************
	int AbstractDraw::DrawTextFormat(ID3DXFont* Font, ID3DXSprite* Sprite, Rectangle2 Rect, D3DCOLOR Color, DrawTextType Type, wchar_t* text, ...)
	{
		wchar_t Buffer[512];
		
        va_list args;
        va_start(args, text);

		vswprintf(Buffer, text, args);

		va_end(args);

		return AbstractDraw::DrawText(Font, Sprite, Rect, Color, Type, Buffer);
	}

	//************************************
	// Method:    FontResetA
	// Profit:	  Calls OnLostDevice
	// FullName:  SD_Tools::AbstractDraw::FontResetA
	// Returns:   HRESULT
	// Notes:
	// -Is just a Wrapper for Font::OnLostDevice
	// -Must be called before Device::Reset
	//************************************
	HRESULT AbstractDraw::FontResetA(ID3DXFont* Font)
	{
		return Font->OnLostDevice();
	}

	//************************************
	// Method:    FontResetB
	// Profit:	  Calls OnResetDevice
	// FullName:  SD_Tools::AbstractDraw::FontResetB
	// Returns:   HRESULT
	// Notes:
	// -Is just wrapper for Font::OnResetDevice
	// -Must be called after Device::Reset
	//************************************
	HRESULT AbstractDraw::FontResetB(ID3DXFont* Font)
	{
		return Font->OnResetDevice();
	}

	//************************************
	// Method:    TextureResetA
	// Profit:	  Calls Release
	// FullName:  SD_Tools::AbstractDraw::TextureResetA
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Texture::Release
	// -Must be called before Device::Reset
	//************************************
	HRESULT AbstractDraw::TextureResetA(IDirect3DTexture9* Texture)
	{
		return Texture->Release();
	}

	//************************************
	// Method:    TextureResetB
	// Profit:	  Calls CreateTexture
	// FullName:  SD_Tools::AbstractDraw::TextureResetB
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for CreateTexture
	// -Recreates the Texture after a Reset - however, the Texture will be blank and must be redrawn
	//************************************
	HRESULT AbstractDraw::TextureResetB(IDirect3DDevice9* Device, UINT Width, UINT Height, IDirect3DTexture9** Texture)
	{
		return CreateTexture(Device, Width, Height, Texture);
	}

	//************************************
	// Method:    TextureResetB
	// Profit:	  Calls CreateTexture
	// FullName:  SD_Tools::AbstractDraw::TextureResetB
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for CreateTexture
	// -Recreates the Texture after a Reset - however, the Texture will be blank and must be redrawn
	//************************************
	HRESULT AbstractDraw::TextureResetB(IDirect3DDevice9* Device, wchar_t* Path, IDirect3DTexture9** Texture)
	{
		return CreateTexture(Device, Path, Texture);
	}

	//************************************
	// Method:    TextureResetB
	// Profit:	  Dummyfunction to maintain style
	// FullName:  SD_Tools::AbstractDraw::TextureResetB
	// Returns:   HRESULT returns D3D_OK in any case
	// Notes:
	// -Is just a Dummy to maintain style
	// -Consists of "return D3D_OK;" and hopefully will be removed by the compiler
	// -You may call it after a Reset - however - to Recreate it either use "CreateTexture" or "TextureResetB" with parameters
	//************************************
	HRESULT AbstractDraw::TextureResetB( IDirect3DDevice9* Device, IDirect3DTexture9** Texture )
	{
		return D3D_OK;
	}

	//************************************
	// Method:    StateBlockResetA
	// Profit:	  Releases a Stateblock
	// FullName:  SD_Tools::AbstractDraw::StateBlockResetA
	// Returns:   HRESULT
	// Notes:
	// -is just a wrapper for StateBlock::Release
	// -Call this before Device::Reset
	//************************************
	HRESULT AbstractDraw::StateBlockResetA(IDirect3DStateBlock9* StateBlock)
	{
		return StateBlock->Release();
	}

	//************************************
	// Method:    StateBlockResetB
	// Profit:	  Recreates a StateBlock
	// FullName:  SD_Tools::AbstractDraw::StateBlockResetB
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Device::CreateStateBlock with D3DSBT_ALL
	// -Call it after a Reset to recreate your Stateblock
	//************************************
	HRESULT AbstractDraw::StateBlockResetB(IDirect3DDevice9* Device, IDirect3DStateBlock9** StateBlock)
	{
		return Device->CreateStateBlock(D3DSBT_ALL, StateBlock);
	}

	//************************************
	// Method:    CreateTextureRectangle
	// Profit:	  Creates a Texture Rectangle
	// FullName:  SD_Tools::AbstractDraw::CreateTextureRectangle
	// Returns:   int
	// Notes:
	// -Size = 6
	//************************************
	int AbstractDraw::CreateTextureRectangle(TEXVERTEX* Buffer, Rectangle2 Rect)
	{
		if (Buffer)
		{
			Buffer[0].rhw = 1.0f;
			Buffer[0].tu = 0.0f;
			Buffer[0].tv = 0.0f;
			Buffer[0].x = Rect.x;
			Buffer[0].y = Rect.y;
			Buffer[0].z = 0.0f;

			Buffer[1].rhw = 1.0f;
			Buffer[1].tu = 1.0f;
			Buffer[1].tv = 0.0f;
			Buffer[1].x = Rect.x+Rect.w;
			Buffer[1].y = Rect.y;
			Buffer[1].z = 0.0f;

			Buffer[2].rhw = 1.0f;
			Buffer[2].tu = 0.0f;
			Buffer[2].tv = 1.0f;
			Buffer[2].x = Rect.x;
			Buffer[2].y = Rect.y+Rect.h;
			Buffer[2].z = 0.0f;


			Buffer[3].rhw = 1.0f;
			Buffer[3].tu = 1.0f;
			Buffer[3].tv = 0.0f;
			Buffer[3].x = Rect.x+Rect.w;
			Buffer[3].y = Rect.y;
			Buffer[3].z = 0.0f;

			Buffer[4].rhw = 1.0f;
			Buffer[4].tu = 0.0f;
			Buffer[4].tv = 1.0f;
			Buffer[4].x = Rect.x;
			Buffer[4].y = Rect.y+Rect.h;
			Buffer[4].z = 0.0f;

			Buffer[5].rhw = 1.0f;
			Buffer[5].tu = 1.0f;
			Buffer[5].tv = 1.0f;
			Buffer[5].x = Rect.x+Rect.w;
			Buffer[5].y = Rect.y+Rect.h;
			Buffer[5].z = 0.0f;
		}
		return SIZE_RECT;
	}

	//************************************
	// Method:    SetTexture
	// Profit:	  Sets the given Texture
	// FullName:  SD_Tools::AbstractDraw::SetTexture
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Device::SetTexture
	//************************************
	HRESULT AbstractDraw::SetTexture(IDirect3DDevice9* Device, IDirect3DTexture9* Texture)
	{
		return Device->SetTexture(0, Texture);
	}

	//************************************
	// Method:    DrawBuffer
	// Profit:	  Draws a Buffer
	// FullName:  SD_Tools::AbstractDraw::DrawBuffer
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Device::DrawPrimitiveUP
	//************************************
	HRESULT AbstractDraw::DrawBuffer(IDirect3DDevice9* Device, D3DPRIMITIVETYPE Type, UINT NumberOfPrimitives, SHAPEVERTEX* Buffer)
	{
		return Device->DrawPrimitiveUP(Type, NumberOfPrimitives, Buffer, sizeof(SHAPEVERTEX));
	}

	//************************************
	// Method:    DrawPointBuffer
	// Profit:	  Draws a PointBuffer
	// FullName:  SD_Tools::AbstractDraw::DrawPointBuffer
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Device::DrawPrimitiveUP with D3DPT_POINTLIST
	//************************************
	HRESULT AbstractDraw::DrawPointBuffer(IDirect3DDevice9* Device, UINT NumberOfVertices, SHAPEVERTEX* Buffer)
	{
		return Device->DrawPrimitiveUP(D3DPT_POINTLIST, NumberOfVertices, Buffer, sizeof(SHAPEVERTEX));
	}

	//************************************
	// Method:    DrawLineBuffer
	// Profit:	  Draws a LineBuffer
	// FullName:  SD_Tools::AbstractDraw::DrawLineBuffer
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Device::DrawPrimitiveUP with D3DPT_LINELIST
	//************************************
	HRESULT AbstractDraw::DrawLineBuffer(IDirect3DDevice9* Device, UINT NumberOfVertices, SHAPEVERTEX* Buffer)
	{
		return Device->DrawPrimitiveUP(D3DPT_LINELIST, NumberOfVertices/2, Buffer, sizeof(SHAPEVERTEX));
	}

	//************************************
	// Method:    DrawTriangleBuffer
	// Profit:	  Draws a TriangleBuffer
	// FullName:  SD_Tools::AbstractDraw::DrawTriangleBuffer
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Device::DrawPrimitiveUP with D3DPT_TRIANGLELIST
	//************************************
	HRESULT AbstractDraw::DrawTriangleBuffer(IDirect3DDevice9* Device, UINT NumberOfVertices, SHAPEVERTEX* Buffer)
	{
		return Device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, NumberOfVertices/3, Buffer, sizeof(SHAPEVERTEX));
	}

	//************************************
	// Method:    DrawTextureBuffer
	// Profit:	  Draws a Triangle Texture Buffer
	// FullName:  SD_Tools::AbstractDraw::DrawTextureBuffer
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Device::DrawPrimitiveUP with D3DPT_TRIANGLELIST
	//************************************
	HRESULT AbstractDraw::DrawTextureBuffer( IDirect3DDevice9* Device, UINT NumberOfVertices, TEXVERTEX* Buffer )
	{
		return Device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, NumberOfVertices/3, Buffer, sizeof(TEXVERTEX));
	}

	//************************************
	// Method:    CreateTexture
	// Profit:	  Creates a Texture in the given size
	// FullName:  SD_Tools::AbstractDraw::CreateTexture
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for Device::CreateTexture with "Width, Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, Texture, NULL"
	//************************************
	HRESULT AbstractDraw::CreateTexture(IDirect3DDevice9* Device, UINT Width, UINT Height, IDirect3DTexture9** Texture)
	{
		return Device->CreateTexture(Width, Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, Texture, NULL);
	}

	//************************************
	// Method:    CreateTexture
	// Profit:	  Creates a Texture from a file
	// FullName:  SD_Tools::AbstractDraw::CreateTexture
	// Returns:   HRESULT
	// Notes:
	// -Is just a wrapper for D3DXCreateTextureFromFile
	//************************************
	HRESULT AbstractDraw::CreateTexture(IDirect3DDevice9* Device, wchar_t* Path, IDirect3DTexture9** Texture)
	{
		return D3DXCreateTextureFromFile(Device, Path, Texture);
	}

	//************************************
	// Method:    BeginTextureRender
	// Profit:	  Prepares TextureRendering
	// FullName:  SD_Tools::AbstractDraw::BeginTextureRender
	// Returns:   HRESULT
	// Notes:
	// -Saves the old Surface and sets the RenderTarget
	//************************************
	HRESULT AbstractDraw::BeginTextureRender(IDirect3DDevice9* Device, IDirect3DTexture9* Texture, IDirect3DSurface9** OldSurface)
	{
		IDirect3DSurface9* NewSurface;
		HRESULT temp;
		Texture->GetSurfaceLevel(0, &NewSurface);
		Device->GetRenderTarget(0, OldSurface);

		temp = Device->SetRenderTarget(0, NewSurface);

		NewSurface->Release();

		return temp;
	}

	//************************************
	// Method:    EndTextureRender
	// Profit:	  Ends the Texture Rendering
	// FullName:  SD_Tools::AbstractDraw::EndTextureRender
	// Returns:   HRESULT
	// Notes:
	// -Sets the old Surface back.
	//************************************
	HRESULT AbstractDraw::EndTextureRender(IDirect3DDevice9* Device, IDirect3DSurface9* OldSurface)
	{
		HRESULT temp = Device->SetRenderTarget(0, OldSurface);
		OldSurface->Release();
		return temp;
	}

	//************************************
	// Method:    ClearRenderTarget
	// Profit:	  Clears the RenderTarget with 0x00000000
	// FullName:  SD_Tools::AbstractDraw::ClearRenderTarget
	// Returns:   HRESULT
	// Notes:
	// -Is just a Wrapper for Device::Clear with "0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0"
	//************************************
	HRESULT AbstractDraw::ClearRenderTarget( IDirect3DDevice9* Device )
	{
		return Device->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
	}

	//************************************
	// Method:    SetFVF
	// Profit:	  Sets the given FVF
	// FullName:  SD_Tools::AbstractDraw::SetFVF
	// Returns:   HRESULT
	// Notes:
	// -Is just a Wrapper for Device::SetFVF
	//************************************
	HRESULT AbstractDraw::SetFVF( IDirect3DDevice9* Device, DWORD FVF )
	{
		return Device->SetFVF(FVF);
	}
}
